package com.dd.cloud.user.service.admin.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dd.cloud.common.constants.AdminConstants;
import com.dd.cloud.common.enums.ZkExceptionEnum;
import com.dd.cloud.common.exception.ZekeException;
import com.dd.cloud.common.interceptor.UserInterceptor;
import com.dd.cloud.common.utils.ObjectUtils;
import com.dd.cloud.common.vo.LoginInfo;
import com.dd.cloud.user.entity.admin.ProblemHelp;
import com.dd.cloud.user.entity.admin.ProblemHelpType;
import com.dd.cloud.user.mapper.admin.ProblemHelpTypeMapper;
import com.dd.cloud.user.req.admin.AddProblemHelpTypeReq;
import com.dd.cloud.user.req.admin.UpdateProblemHelpTypeReq;
import com.dd.cloud.user.service.admin.IProblemHelpService;
import com.dd.cloud.user.service.admin.IProblemHelpTypeService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 问题类型表 服务实现类
 * </p>
 *
 * @author czg
 * @since 2023-09-13
 */
@Service
public class ProblemHelpTypeServiceImpl extends ServiceImpl<ProblemHelpTypeMapper, ProblemHelpType> implements IProblemHelpTypeService {
    @Autowired
    private IProblemHelpService problemHelpService;

    /**
     * 查询问题类型列表
     *
     * @param status
     * @return
     */
    @Override
    public List<ProblemHelpType> getProblemTypeList(Integer status) {
        return getBaseMapper().getProblemTypeList(status);
    }

    /**
     * @param req:
     * @return void
     * @description 添加问题类型
     * @author czg
     * @date 2023/9/13 17:40
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addProblemHelpType(AddProblemHelpTypeReq req) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        QueryWrapper<ProblemHelpType> qw = new QueryWrapper<>();
        qw.lambda().eq(ProblemHelpType::getTitle, req.getTitle()).ne(ProblemHelpType::getStatus, AdminConstants.ProblemHelpTypeStatus.DEL);
        List<ProblemHelpType> list = list(qw);
        if (list != null && !list.isEmpty()) {
            throw new ZekeException("问题类型名称已存在");
        }
        ProblemHelpType problemHelpType = new ProblemHelpType();
        BeanUtils.copyProperties(req, problemHelpType);
        problemHelpType.setCreateDate(LocalDateTime.now());
        problemHelpType.setCreateId(loginInfo.getId());
        int sort = cumProblemHelpTypeSort(req.getSort(), null);
        problemHelpType.setSort(sort);
        boolean save = save(problemHelpType);
        if (!save) {
            throw new ZekeException("添加失败");
        }
        getBaseMapper().updateProblemHelpTypeReorder();
    }

    /**
     * @param req:
     * @return void
     * @description 修改问题类型
     * @author czg
     * @date 2023/9/13 17:40
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateProblemHelpType(UpdateProblemHelpTypeReq req) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        ProblemHelpType byId = getById(req.getId());
        if (byId == null) {
            throw new ZekeException("问题类型不存在");
        }
        if (!byId.getTitle().equals(req.getTitle())) {
            QueryWrapper<ProblemHelpType> qw = new QueryWrapper<>();
            qw.lambda().eq(ProblemHelpType::getTitle, req.getTitle()).ne(ProblemHelpType::getStatus, AdminConstants.ProblemHelpTypeStatus.DEL);
            List<ProblemHelpType> list = list(qw);
            if (list != null && !list.isEmpty()) {
                throw new ZekeException("问题类型名称已存在");
            }
        }

        int sort = cumProblemHelpTypeSort(req.getSort(), byId.getSort());
        BeanUtils.copyProperties(req, byId);
        byId.setCreateDate(LocalDateTime.now());
        byId.setCreateId(loginInfo.getId());
        byId.setSort(sort);
        boolean save = updateById(byId);
        if (!save) {
            throw new ZekeException("修改失败");
        }
        getBaseMapper().updateProblemHelpTypeReorder();
    }

    /**
     * @param id:
     * @param status:
     * @return void
     * @description 修改问题类型状态
     * @author czg
     * @date 2023/9/13 17:40
     */
    @Override
    public void updateProblemHelpTypeStatus(Integer id, Integer status) {
        ProblemHelpType help = getById(id);
        if (help == null) {
            throw new ZekeException(400, "问题帮助不存在");
        }
        if (!ObjectUtils.refrect(AdminConstants.ProblemHelpTypeStatus.class, status)) {
            throw new ZekeException(ZkExceptionEnum.STATUS_DATA_ERROR);
        }
        if (status.equals(help.getStatus())) {
            return;
        }
        help.setStatus(status);
        boolean i = updateById(help);
        if (!i) {
            throw new ZekeException("修改失败");
        }
        if (status == AdminConstants.ProblemHelpTypeStatus.DEL) {
            //删除问题类型判断是否有下级问题
            QueryWrapper<ProblemHelp> qw = new QueryWrapper<>();
            qw.lambda().eq(ProblemHelp::getTypeId, id).ne(ProblemHelp::getStatus, AdminConstants.ProblemHelpTypeStatus.DEL);
            int count = problemHelpService.count(qw);
            if (count > 0) {
                throw new ZekeException(400, "该问题类型下有问题数据,无法删除");
            }
        }
        if (status != AdminConstants.ProblemHelpTypeStatus.NORMAL) {
            //禁用问题类型后 并禁用问题 删除问题类型后 并删除问题
            UpdateWrapper<ProblemHelp> uw = new UpdateWrapper<>();
            uw.lambda().eq(ProblemHelp::getTypeId, id).ne(ProblemHelp::getStatus, AdminConstants.ProblemHelpTypeStatus.DEL).set(ProblemHelp::getStatus, status);
            problemHelpService.update(uw);
        }
    }

    /**
     * 问题帮助类型重排序
     *
     * @param oldSort 新排序位置
     * @param newSort 旧排序位置
     * @return 目标位置
     */
    @Transactional(rollbackFor = Exception.class)
    public int cumProblemHelpTypeSort(Integer newSort, Integer oldSort) {
        if (oldSort == null) {
            //没有原位置, 为新增
            //先进行重排序
            getBaseMapper().updateProblemHelpTypeReorder();
            if (newSort == null) {
                QueryWrapper<ProblemHelpType> qu = new QueryWrapper<>();
                qu.lambda().orderByDesc(ProblemHelpType::getSort).last("limit 1");
                ProblemHelpType content = getOne(qu);
                if (content == null) {
                    return 1;
                }
                return content.getSort() + 1;
            }
            UpdateWrapper<ProblemHelpType> uw = new UpdateWrapper<>();
            uw.lambda().ge(ProblemHelpType::getSort, newSort).ne(ProblemHelpType::getStatus, AdminConstants.ProblemHelpTypeStatus.DEL).setSql("`sort` = `sort` + 1");
            update(uw);
            return newSort;
        }
        if (newSort.equals(oldSort)) {
            return newSort;
        }
        //有原位置, 为修改, 只用修改两个位置之间的数据即可
        if (newSort > oldSort) {
            //后移
            UpdateWrapper<ProblemHelpType> uw = new UpdateWrapper<>();
            uw.lambda().le(ProblemHelpType::getSort, newSort).ge(ProblemHelpType::getSort, oldSort).ne(ProblemHelpType::getStatus, AdminConstants.ProblemHelpTypeStatus.DEL).setSql("`sort` = `sort` - 1");
            update(uw);
            return newSort;
        } else {
            //前移
            UpdateWrapper<ProblemHelpType> uw = new UpdateWrapper<>();
            uw.lambda().lt(ProblemHelpType::getSort, oldSort).ge(ProblemHelpType::getSort, newSort).ne(ProblemHelpType::getStatus, AdminConstants.ProblemHelpTypeStatus.DEL).setSql("`sort` = `sort` + 1");
            update(uw);
            return newSort;
        }
    }
}
